<?php
namespace Api;

class Api
{

    public $db = NULL;

    public $router = NULL;

    public $api_prefix = '';
    // 接口前缀
    public $api_method = '';
    // 接口名称
    public $method_exists = '';
    // 接口是否存在
    public $_time = '';
    // 接口访问时间
    public $_is_log = '';
    // 是否写日志
    public $_system_input_id = 0;
    // 系统输入参数 ID
    public $_application_input_id = 0;
    // 应用输入参数 ID
    public $_response_id = 0;
    // 接口返回限制条件 ID
    public $header;

    function __construct()
    {
        $this->api_prefix = 'iasku'; // 暂定，可修改 iasku.question.get
        $CI = & get_instance();
        $this->db = $CI->db;
        $this->router = $CI->router;
        $CI->load->library('cache');
        $this->cache = $CI->cache;
        
        $CI->load->library('token');
        $this->token = $CI->token;
        $this->_user = $this->token->user();
        
        $this->_get_api_method(); // 获得接口名称
                                  // dump($this->router);exit();
        $this->_time = $_SERVER['REQUEST_TIME']; // 脚本执行开始时间
        $this->_is_log = true; // 错误日志 true: 打开 false: 关闭
        if ($this->cache->is_connect === false) {
            exec("redis-server E:/Redis/conf/redis.conf"); // 重启redis服务
        }
        
        $this->_wait_a_moment();
    }

    /**
     * 接口是否存在
     * 0 : 接口不存在 1: 接口存在 2: 接口重复，错误
     */
    private function _method_exists()
    {
        if ($this->api_method != '') {
            $cache_key = $this->api_method;
            $r = $this->cache->get($cache_key);
            
            if ($r === false || 1) {
                $r = $this->db->select('system_input_id, application_input_id, response_id')
                    ->from(TABLE_API2_METHOD)
                    ->where('method_name_en', $this->api_method)
                    ->get()
                    ->row_array(0);
                // echo $this->db->last_query();
                // var_dump($r);exit;
                
                if (! empty($r))
                    $this->cache->set($cache_key, json_encode($r), false, CACHE_TIME_7_D);
            } else {
                $r = json_decode($r, true);
            }
            
            if ($r) {
                $this->_system_input_id = $r['system_input_id'];
                $this->_application_input_id = $r['application_input_id'];
                $this->_response_id = $r['response_id'];
            }
        } else
            $r = 0;
        
        return $r;
    }

    /**
     * 获得接口名称
     */
    private function _get_api_method()
    {
        return $this->api_method = $this->api_prefix . '.' . implode('.', $this->router->uri->segments);
    }

    /**
     * 接口不能重复刷新
     */
    public function _wait_a_moment()
    {
        // TODO 接口重复刷新时间
        // dump($this->_user);exit;
    }

    /**
     * 对api输入参数 进行规划
     */
    public function _input($param)
    {
        if (isset($param['debug'])) {
            unset($param['debug']);
            error_reporting(E_ALL ^ E_NOTICE);
        }
        // dump($this->_method_exists());exit;
        
        if (! $this->_method_exists())
            $this->_output('', 1, '接口不存在'); // 判断接口是否存在
        
        $input = array(); // 经过接口输入要求过滤后的输入参数
                          
        // if(!empty($param))
                          // {
        $arr_input = array(); // 接口限制条件数组
                              
        // 系统输入
        if ($this->_system_input_id) {
            $cache_key_system = $this->_system_input_id;
            
            $arr_input = $this->cache->get($cache_key_system);
            
            if ($arr_input === false || 1) {
                $sql = "SELECT b.cate_type, b.cate_name, a.* FROM " . TABLE_API2_FIELD . " a, " . TABLE_API2_CATEGORY . " b
                        WHERE a.obj_id = b.id AND a.item_id = " . $this->_system_input_id . "";
                // echo $sql;exit;
                $arr_input = $this->db->query($sql)->result_array();
                
                if ($arr_input)
                    $this->cache->set($cache_key_system, json_encode($arr_input), false, CACHE_TIME_7_D);
            } else
                $arr_input = json_decode($arr_input, true);
                
                // dump($arr_input);exit;
                // token 验证
            if (! empty($arr_input)) {
                foreach ($arr_input as $v) {
                    // dump($v);exit;
                    if (isset($v['field_name']) && $v['field_name'] == 'token' && $v['is_necessary'] == 1) {
                        $this->need_token($param['token']);
                    }
                }
            }
        }
        
        // 应用输入
        if ($this->_application_input_id) {
            $cache_key_input = $this->_application_input_id;
            
            $arr_input_2 = $this->cache->get($cache_key_input);
            
            if ($arr_input_2 === false || 1) {
                $sql = "SELECT b.cate_type, b.cate_name, a.* FROM " . TABLE_API2_FIELD . " a, " . TABLE_API2_CATEGORY . " b
                        WHERE a.obj_id = b.id AND a.item_id = " . $this->_application_input_id;
                $arr_input_2 = $this->db->query($sql)->result_array();
                
                if ($arr_input_2)
                    $this->cache->set($cache_key_input, json_encode($arr_input_2), false, CACHE_TIME_7_D);
            } else
                $arr_input_2 = json_decode($arr_input_2, true);
            
            $arr_input = array_merge($arr_input, $arr_input_2);
        }
        
        // unset 为空的参数
        if (! empty($param)) {
            foreach ($param as $k => $v) {
                if ($v == '')
                    unset($param[$k]);
            }
        }
        // dump($param);exit;
        // dump($arr_input);exit;
        if (! empty($arr_input)) {
            // 循环接口输入条件，依条件判断输入参数，数据是否合法，是否必须，是否默认值
            foreach ($arr_input as $k => $v) {
                $field_type = trim($v['cate_name']); // 字段类型
                $field_name = trim($v['field_name']); // 字段名称
                if ((isset($param[$field_name]) && $field_name != '') || isset($_FILES[$field_name])) {
                    if ($field_type == 'Int') {
                        $input[$field_name] = (int) (trim($param[$field_name]));
                    } elseif ($field_type == 'File') {
                        if ($_FILES[$field_name])
                            $input[$field_name] = $_FILES[$field_name]; // FILES
                    } else {
                        if ($field_type == 'String')
                            $input[$field_name] = $param[$field_name]; // string
                    }
                } else {
                    if ($v['is_necessary']) { // 1:yes
                        $this->_output('', 1, '[(' . $field_type . ')' . $field_name . '] 是必须, 不能为空');
                    } elseif (isset($v['default_value']) && $v['default_value'] != '') {
                        $input[$field_name] = $v['default_value'];
                    }
                }
            }
            // dump($input);
        }
        unset($param);
        // }
        // print_r($input);exit();
        return $input;
    }

    /**
     * 先验证 token
     */
    public function need_token($token = '')
    {
        $detail = $this->cache->get($token);
        
        if (CACHE_FLAG || empty($detail)) {
            $result = $this->db->get_where(TABLE_MEMBER_TOKEN, array(
                'token' => $token
            ))->row_array(0);
        } else {
            $detail = json_decode($detail, true);
            $result = $detail['token'];
        }
        
        if (count($result) < 1) {
            $this->_output('', 401, 'token不存在！');
        }
        
        if ($result['over_time'] <= $_REQUEST['REQUEST_TIME']) {
            $this->_output('', 402, 'token已经过期！');
        }
    }

    /**
     * error_no : 错误类型 (0: 正常 非0：消息提示)
     * error_msg : 消息提示
     * result : 返回结果
     */
    public function _output($result, $error_no = 200, $error_msg = '', $callback = '')
    {
        $output = array();
        $output['error_no'] = intval($error_no);
        
        // if ($result == '' && $error_msg != '') {
        // $result = '';
        // } else {
        // $error_msg = '';
        // }
        
        $output['error_msg'] = $error_msg;
        $output['result'] = $result;
        
        unset($result);
        
        // 有错误写入日志
        // if ($output['error_no'] != 200)
        $this->_do_log(var_export($output, true),$output['error_no']);
        
        if (isset($_REQUEST['t']) && $_REQUEST['t'] == 'a') {
            if (isset($_REQUEST['sql']) && $_REQUEST['sql'] == true && DUMP_SQL) {
                dump($this->db->queries);
                exit();
            }
            dump($output);
            exit();
        } else {
            exit(json_encode($output));
        }
    }

    /**
     * 用数据库API日志
     */
    private function _do_log($str,$error_no)
    {
        if ($this->_is_log == TRUE) {
            $data = array();
            if (isset($this->_user)) {
                $data['uid'] =$this->_user['user']['uid'];
                $data['username'] = $this->_user['user']['user_name'];
            }
            $data['action'] = $this->api_method;
            $data['url'] = $_SERVER['REQUEST_URI'];
            $data['error_no'] = $error_no;
            $data['msg'] = serialize($str);
            $data['script_time'] = time() - $this->_time; // api 脚本执行时间
            $data['create_time'] = date('Y-m-d H:i:s', $this->_time);
            $this->db->insert(TABLE_API2_LOG, $data);
        }
    }
}

?>
